﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Data.SqlServerCe;
using System.IO;

namespace RefOffDesktop
{
    /*
     * Class: Match
     * 
     * Use: Represents a Match within the system. Displayed as a form
     *      called Match Details, containing tabs to show Goals, Cautions,
     *      Sending Offs, Reports and Virtual Pitch for the Match
     *      
     * Author: Mike Skaife, mcs3@aber.ac.uk
     */ 
    public partial class Match : Form
    {
        //The main RefOff screen from
        //where this form was opened
        public RefOff referrer;
        
        //Details required to connect to database
        string conString;
        SqlCeConnection conn;
        String desktop_connection = @"Data Source=RefOff_DB.sdf";

        //Attributes of the Match
        private int mMatch_id;
        private DateTime mDb_date;
        private String mDate;
        private int mHomeId;
        private String mHomeTeam;
        private String mHomeSquad;
        private int mAwayId;
        private String mAwayTeam;
        private String mAwaySquad;
        private String mCompetition;
        private String mAssociation;

        //List of objects related to the Match
        public List<Goal> matchGoals;
        public List<Caution> matchCautions;
        public List<SendOff> matchSendOffs;
        public List<String> matchReports;
        public List<Player> matchHomePlayers;
        public List<Player> matchAwayPlayers;
        public List<VirtualPitchIncident> vpDetails;

        //Virtual Pitch mapping class for the Match
        private VirtualPitchMapper m_mapper;
        private Graphics m_graphics;

        //Variable used to obtain the current position
        //in the list of Virtual Pitch incidents that the
        //user has scrolled to
        int vpCounter = 0;
        
        public Match()
        {
            InitializeComponent();
            referrer = null;
            matchGoals = new List<Goal>();
            matchCautions = new List<Caution>();
            matchSendOffs = new List<SendOff>();
            matchReports = new List<String>();
            matchHomePlayers = new List<Player>();
            matchAwayPlayers = new List<Player>();
            vpDetails = new List<VirtualPitchIncident>();
            m_graphics = matchVPBox.CreateGraphics();
            m_mapper = new VirtualPitchMapper(m_graphics, 0, 0, 600, 382);
            setListViewColors();
        }        

        //Method used to colour the lists within the Match Details screen
        public void setListViewColors()
        {
            //Go through all items in Goal list and colour them
            for (int i = 0; i < matchGoalLst.Items.Count; i++)
            {
                if (i % 2 == 0)
                {
                    ListViewItem nextItem = matchGoalLst.Items[i];
                    nextItem.BackColor = Color.SkyBlue;
                }
            }

            //Go through all items in Caution list and colour them
            for (int i = 0; i < matchCautionLst.Items.Count; i++)
            {
                if (i % 2 == 0)
                {
                    ListViewItem nextItem = matchCautionLst.Items[i];
                    nextItem.BackColor = Color.SkyBlue;
                }
            }

            //Go through all items in Sending Off list and colour them
            for (int i = 0; i < matchSendoffLst.Items.Count; i++)
            {
                if (i % 2 == 0)
                {
                    ListViewItem nextItem = matchSendoffLst.Items[i];
                    nextItem.BackColor = Color.SkyBlue;
                }
            }
        }

        //Setter and getter for database id of this Match
        public int match_id
        {
            get
            {
                return mMatch_id;
            }

            set
            {
                mMatch_id = value;
            }
        }

        //Setter and getter for date of Match as stored in database
        public DateTime db_date
        {
            get
            {
                return mDb_date;
            }

            set
            {
                mDb_date = value;
            }
        }

        //Setter and getter for formatted Match date for use in Match Details screen
        public String date
        {
            get
            {
                return mDate;
            }

            set
            {
                mDate = value;
            }
        }

        //Setter and getter for database id of home team
        public int homeId
        {
            get
            {
                return mHomeId;
            }

            set
            {
                mHomeId = value;
            }
        }

        //Setter and getter for name of home team
        public String homeTeam
        {
            get
            {
                return mHomeTeam;
            }

            set
            {
                mHomeTeam = value;
            }
        }

        //Setter and getter for home team squad, i.e. 1st, u18, etc.
        public String homeSquad
        {
            get
            {
                return mHomeSquad;
            }

            set
            {
                mHomeSquad = value;
            }
        }

        //Setter and getter for database id of away team
        public int awayId
        {
            get
            {
                return mAwayId;
            }

            set
            {
                mAwayId = value;
            }
        }

        //Setter and getter for name of away team
        public String awayTeam
        {
            get
            {
                return mAwayTeam;
            }

            set
            {
                mAwayTeam = value;
            }
        }

        //Setter and getter for away team squad, i.e. 1st, u18, etc.
        public String awaySquad
        {
            get
            {
                return mAwaySquad;
            }

            set
            {
                mAwaySquad = value;
            }
        }

        //Setter and getter for competition Match was played in
        public String competition
        {
            get
            {
                return mCompetition;
            }

            set
            {
                mCompetition = value;
            }
        }

        //Setter and getter for football association covering this Match
        public String association
        {
            get
            {
                return mAssociation;
            }

            set
            {
                mAssociation = value;
            }
        }

        //Method called when the 'Generate Reports' button is clicked
        private void matchReportsGenBtn_Click(object sender, EventArgs e)
        {
            //Create a new ReportGenerator object, passing in this Match
            ReportGenerator gen = new ReportGenerator(this);

            //Complete all the required misconduct reports
            gen.fillForms();
        }        

        //Method called when the 'Close' button is clicked
        private void matchCloseBtn_Click(object sender, EventArgs e)
        {
            //Hide this form and display the main RefOff screen
            referrer.Enabled = true;
            this.Visible = false;
        }

        //Method called when user clicks on an item in the List of Goals
        private void matchGoalLst_DoubleClick(object sender, EventArgs e)
        {
            //Obtain index of item that was clicked
            int ind = matchGoalLst.SelectedItems[0].Index;
            matchGoals[ind].referrer = this;

            //Disble this form and open the relevant Goal form
            this.Enabled = false;
            matchGoals[ind].Visible = true;
        }

        //Method called when an item in the Caution tab is clicked
        private void matchCautionLst_DoubleClick(object sender, EventArgs e)
        {
            //Obtain index of item that was clicked
            int ind = matchCautionLst.SelectedItems[0].Index;
            matchCautions[ind].referrer = this;

            //Disble this form and open the relevant Caution form
            this.Enabled = false;
            matchCautions[ind].Visible = true;
        }

        //Method called when an item in the Sending Off tab is clicked
        private void matchSendoffLst_DoubleClick(object sender, EventArgs e)
        {
            //Obtain index of item that was clicked
            int ind = matchSendoffLst.SelectedItems[0].Index;
            matchSendOffs[ind].referrer = this;

            //Disble this form and open the relevant Caution form
            this.Enabled = false;
            matchSendOffs[ind].Visible = true;
        }

        //Method called when a report filename is clicked on in the Reports tab
        private void matchReportsLst_DoubleClick(object sender, EventArgs e)
        {
            //Obtain index of item that was clicked
            int ind = matchReportsLst.SelectedItems[0].Index;

            //Open the selected file in Adobe Reader
            String fileToOpen = matchReports[ind];
            Process.Start(@"CompletedReports\" + fileToOpen);
        }

        //Method used to parse a GPS sentence as a Point
        //for use on Virtual Pitch. Calls method in
        //VirtualPitchMapper class
        public Point parse(String gps_reading)
        {
            Point parsedLocation = new Point();
            parsedLocation = m_mapper.parseAndDraw(gps_reading);
            return parsedLocation;
        }        

        //Method called when user scrolls forwards through Virtual Pitch incidents
        private void matchVPPrevBtn_Click(object sender, EventArgs e)
        {
            //Obtain number of incidents within the Match
            int position = vpDetails.Count;

            //Check that there is another incident in the
            //List after the one currently displayed
            if ((vpCounter-1) < position && (vpCounter-1) >= 0)
            {
                //Decrement the counter indicating the current incident
                vpCounter--;

                //Obtain the two points to be mapped - whistle and incident
                List<Point> pointsToMap = vpDetails[vpCounter].vpPoints;

                //Clear the graphics area of previously displayed incident
                m_graphics.Clear(Color.Green);

                //Set scale of Virtual Pitch
                m_mapper.Scale = 0.011F;

                //draw new incident onto Virtual Pitch
                matchVPBox.BringToFront();
                m_mapper.clearAndDraw(pointsToMap);
                
                //Set values of text boxes showing incident information below Virtual Pitch
                matchVPDistanceTxt.Text = vpDetails[vpCounter].distance + "m";
                matchVPIncidentTxt.Text = vpDetails[vpCounter].incident;
                matchVPPlayerTxt.Text = vpDetails[vpCounter].player;
                matchVPTimeTxt.Text = vpDetails[vpCounter].time;                
            }
            else
            {
                //If there are no more incidents in
                //this scrolling direction, tell the user
                MessageBox.Show("No more incidents");
            }
        }

        //Method called when user scrolls backwards through Virtual Pitch incidents
        private void matchVPNextBtn_Click(object sender, EventArgs e)
        {
            //Obtain number of incidents within the Match
            int position = vpDetails.Count;

            //Check that there is another incident in the
            //List before the one currently displayed
            if (vpCounter < position && vpCounter >= 0)
            {
                //Obtain the two points to be mapped - whistle and incident
                List<Point> pointsToMap = vpDetails[vpCounter].vpPoints;

                //Clear the graphics area of previously displayed incident
                m_graphics.Clear(Color.Green);

                //Set scale of Virtual Pitch
                m_mapper.Scale = 0.011F;

                //draw new incident onto Virtual Pitch
                matchVPBox.BringToFront();
                m_mapper.clearAndDraw(pointsToMap);

                //Set values of text boxes showing incident information below Virtual Pitch                
                matchVPDistanceTxt.Text = String.Format("{0:0.00}", vpDetails[vpCounter].distance) + "m";
                matchVPIncidentTxt.Text = vpDetails[vpCounter].incident;
                matchVPPlayerTxt.Text = vpDetails[vpCounter].player;
                matchVPTimeTxt.Text = vpDetails[vpCounter].time;

                //Increment the counter indicating the current incident
                vpCounter++;
            }
            else
            {
                //If there are no more incidents in
                //this scrolling direction, tell the user
                MessageBox.Show("No more incidents");
            }
        }

        //Method used to delete incidents from the Match, depending on
        //which tab is currently selected. If no item is selected then an
        //error message is displayed to the user
        private void matchDeleteBtn_Click(object sender, EventArgs e)
        {
            //Get the index of the currently selected tab
            int selectedTab = MatchTabCtrl.SelectedIndex;
            
            //If the index is 0 we are dealing with Goals
            if (selectedTab == 0)
            {
                //Check a Goal in the list has been selected
                if (matchGoalLst.SelectedItems.Count > 0)
                {
                    //Get index of selected Goal
                    int goalIndex = matchGoalLst.SelectedItems[0].Index;

                    //Delete the Goal from the system
                    deleteGoal(goalIndex);                    
                }
                //If no Goal is selected inform the user
                else
                {
                    MessageBox.Show("Please select a Goal to delete");
                }
            }
            //If the index is 1 we are dealing with Cautions
            else if (selectedTab == 1)
            {
                //Check a Caution in the list has been selected
                if (matchCautionLst.SelectedItems.Count > 0)
                {
                    //Get index of selected Caution
                    int cautionIndex = matchCautionLst.SelectedItems[0].Index;

                    //Delete the Caution from the system
                    deleteCaution(cautionIndex);                    
                }
                //If no Caution is selected inform the user
                else
                {
                    MessageBox.Show("Please select a Caution to delete");
                }
            }
            //If the index is 2 we are dealing with Sending Offs
            else if (selectedTab == 2)
            {
                //Check a Sending Off in the list has been selected
                if (matchSendoffLst.SelectedItems.Count > 0)
                {
                    //Get index of selected Sending Off
                    int sendoffIndex = matchSendoffLst.SelectedItems[0].Index;

                    //Delete the Sending Off from the system
                    deleteSendOff(sendoffIndex);
                }
                //If no Caution is selected inform the user
                else
                {
                    MessageBox.Show("Please select a Sending Off to delete");
                }
            }
            //Otherwise we don't need to do anything
            else
            {
                MessageBox.Show("Please select a Goal, Caution or Sending Off to delete");
            }          
        }

        //Method used to connect to the database
        private void connectToDatabase(String connection_string)
        {
            // Retrieve the connection string
            conString = connection_string;

            // Open the connection using the connection string
            conn = new SqlCeConnection(conString);
            conn.Open();
        }

        //Method to disconnect from the database
        private void closeDatabaseConnection()
        {
            //Close the database connection
            conn.Close();
        }

        //Method called to delete Caution from the system
        private void deleteCaution(int selectedId)
        {
            //Index of selected Caution in list on screen
            int cautionIndex = selectedId;

            //Get hold of selected Caution and its id
            Caution tempCaution = matchCautions[cautionIndex];
            int tempCautionId = tempCaution.caution_id;

            //Loop through all Cautions in system and delete this
            //Caution when it is found
            for (int k = 0; k < referrer.cautions.Count; k++)
            {
                if (referrer.cautions[k].caution_id == tempCautionId)
                {
                    referrer.cautions.RemoveAt(k);
                }
            }

            //Loop through all Cautions in this Match and delete
            //the selected Caution when it is found
            for (int l = 0; l < matchCautions.Count; l++)
            {
                if (matchCautions[l].caution_id == tempCautionId)
                {
                    matchCautions.RemoveAt(l);
                }
            }

            //Loop through all Virtual Pitch incidents for the Match
            //and remove the one relating to this Caution
            for (int m = 0; m < vpDetails.Count; m++)
            {
                if (vpDetails[m].id == tempCautionId)
                {
                    vpDetails.RemoveAt(m);
                }
            }

            //Connect to the database
            connectToDatabase(desktop_connection);

            //Create and execute SQL command to delete Caution from database
            string caution_delete_command = @"DELETE FROM caution WHERE caution_id= " + tempCautionId + ";";
            using (SqlCeCommand caution_delete = new SqlCeCommand(caution_delete_command, conn))
            {
                caution_delete.ExecuteNonQuery();
            }

            //Disconnect from database
            closeDatabaseConnection();

            //Remove Caution from list on screen
            matchCautionLst.SelectedItems[0].Remove();

            //De-select all items in the list
            matchCautionLst.SelectedItems.Clear();

            //Re-seed the database
            referrer.getMaximumDBValues(desktop_connection);
        }

        //Method called to delete Goal from the system
        private void deleteGoal(int selectedId)
        {
            //Index of selected Goal within list on screen
            int goalIndex = selectedId;
            
            //Get hold of selected Goal and its id
            Goal tempGoal = matchGoals[goalIndex];
            int tempGoalId = tempGoal.goal_id;

            //Loop through all Goals in system and delete this
            //Goal when it is found
            for (int i = 0; i < referrer.goals.Count; i++)
            {
                if (referrer.goals[i].goal_id == tempGoalId)
                {
                    referrer.goals.RemoveAt(i);
                }
            }

            //Loop through all Goals in this Match and delete
            //the selected Goal when it is found
            for (int j = 0; j < matchGoals.Count; j++)
            {
                if (matchGoals[j].goal_id == tempGoalId)
                {
                    matchGoals.RemoveAt(j);
                }
            }

            //Connect to the database
            connectToDatabase(desktop_connection);

            //Create and execute SQL command to delete Goal from database
            string goal_delete_command = @"DELETE FROM goal WHERE goal_id= " + tempGoalId + ";";
            using (SqlCeCommand goal_delete = new SqlCeCommand(goal_delete_command, conn))
            {
                goal_delete.ExecuteNonQuery();
            }

            //Disconnect from database
            closeDatabaseConnection();

            //Remove goal from list on screen
            matchGoalLst.SelectedItems[0].Remove();

            //De-select all items in the list
            matchGoalLst.SelectedItems.Clear();

            //Re-seed the database
            referrer.getMaximumDBValues(desktop_connection);
        }

        //Method called to delete a Sending Off from the system
        private void deleteSendOff(int selectedId)
        {
            //Index of selected Sending Off in list on screen
            int sendoffIndex = selectedId;

            //Get hold of selected Sending Off and its id
            SendOff tempSendoff = matchSendOffs[sendoffIndex];
            int tempSendoffId = tempSendoff.sendoff_id;

            //Loop through all Sending Offs in system and delete this
            //Sending Off when it is found
            for (int k = 0; k < referrer.sendoffs.Count; k++)
            {
                if (referrer.sendoffs[k].sendoff_id == tempSendoffId)
                {
                    referrer.sendoffs.RemoveAt(k);
                }
            }

            //Loop through all Sending Offs in this Match and delete
            //the selected Sending Off when it is found
            for (int l = 0; l < matchSendOffs.Count; l++)
            {
                if (matchSendOffs[l].sendoff_id == tempSendoffId)
                {
                    matchSendOffs.RemoveAt(l);
                }
            }

            //Loop through all Virtual Pitch incidents for the Match
            //and remove the one relating to this Sending Off
            for (int m = 0; m < vpDetails.Count; m++)
            {
                if (vpDetails[m].id == tempSendoffId)
                {
                    vpDetails.RemoveAt(m);
                }
            }

            //Connect to the database
            connectToDatabase(desktop_connection);

            //Create and execute SQL command to delete Sending Off from database
            string sendoff_delete_command = @"DELETE FROM sendoff WHERE sendoff_id= " + tempSendoffId + ";";
            using (SqlCeCommand sendoff_delete = new SqlCeCommand(sendoff_delete_command, conn))
            {
                sendoff_delete.ExecuteNonQuery();
            }

            //Disconnect from database
            closeDatabaseConnection();

            //Remove Sending Off from list on screen
            matchSendoffLst.SelectedItems[0].Remove();

            //De-select all items in the list
            matchSendoffLst.SelectedItems.Clear();

            //Re-seed the database
            referrer.getMaximumDBValues(desktop_connection);
        }

        //Method used to delete a specified misconduct report from this Match
        private void matchReportsDelSelBtn_Click(object sender, EventArgs e)
        {           
            //Check a Report in the list has been selected
            if (matchReportsLst.SelectedItems.Count > 0)
            {
                //Get index of selected Report
                int reportIndex = matchReportsLst.SelectedItems[0].Index;

                //Loop through all reports for this Match
                for (int i = 0; i < matchReports.Count; i++)
                {
                    //When the selected report is found...
                    if(matchReports[i].Equals(matchReportsLst.Items[reportIndex].Text))
                    {
                        //Remove report from list on screen
                        matchReportsLst.Items.RemoveAt(i);

                        //Delete PDF report file
                        File.Delete(@"CompletedReports\" + matchReports[i]);

                        //Remove report from list of reports for this Match
                        matchReports.RemoveAt(i);
                    }
                }
            }
            //If no Report is selected inform the user
            else
            {
                MessageBox.Show("Please select a Report to delete");
            }
        }

        //Method used to delete all misconduct reports for this Match
        private void matchReportsDelAllBtn_Click(object sender, EventArgs e)
        {           
            //Loop through all reports for this Match
            for (int i = 0; i < matchReports.Count; i++)
            {
                //Delete PDF report file
                File.Delete(@"CompletedReports\" + matchReports[i]);                                
            }

            //Delete report from list of reports for this Match
            matchReports.Clear();

            //Delete report from list on screen
            matchReportsLst.Items.Clear();
        }
    }    
}
